package cc.vv.party.common.handler.exception

import cc.vv.party.common.wrapper.ResponseEntityWrapper
import cc.vv.party.common.wrapper.ResponseEntityWrapper.Companion.error
import cc.vv.party.exception.BizException
import cc.vv.party.common.constants.StatusCode
import org.slf4j.LoggerFactory
import org.springframework.dao.DataIntegrityViolationException
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.MissingServletRequestParameterException
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import javax.validation.ConstraintViolationException

/**
 * @version 1.0.0
 * @author: Gyb
 * @date 2018/8/9
 * @description
 **/
@ControllerAdvice
class GlobalExceptionHandler {

    private val logger by lazy { LoggerFactory.getLogger(GlobalExceptionHandler::class.java) }

    @ExceptionHandler(Throwable::class)
    @ResponseBody
    fun exceptionHandler(e: Exception): ResponseEntityWrapper<Any> {
        logger.error(e.localizedMessage ?: "", e)
        return when (e) {
            is MissingServletRequestParameterException -> error(StatusCode.MISSING_REQUIRE_FIELD)
            is BizException -> error(e.statusCode, e.localizedMessage ?: "")
            is ConstraintViolationException -> {
                error(StatusCode.MISSING_REQUIRE_FIELD.statusCode, e.constraintViolations.first().message)
            }
            is MethodArgumentNotValidException -> {
                val result = e.bindingResult.fieldError?.defaultMessage
                error(StatusCode.MISSING_REQUIRE_FIELD.statusCode, result.toString())
            }
            is DataIntegrityViolationException -> {
                error(StatusCode.FIELD_VALUE_ERROR)
            }
            else -> error(StatusCode.ERROR.statusCode, e.localizedMessage ?: "")
        }
    }
}